home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / sox / sf.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  4KB  |  175 lines

  1. /*
  2.  * July 5, 1991
  3.  * Copyright 1991 Lance Norskog And Sundry Contributors
  4.  * This source code is freely redistributable and may be used for
  5.  * any purpose.  This copyright notice must be maintained. 
  6.  * Lance Norskog And Sundry Contributors are not responsible for 
  7.  * the consequences of using this software.
  8.  */
  9.  
  10. /*
  11.  * Sound Tools IRCAM SoundFile format handler.
  12.  * 
  13.  * Derived from: Sound Tools skeleton handler file.
  14.  */
  15.  
  16. #include "st.h"
  17. #include "sfheader.h"
  18. #include <string.h>
  19.  
  20. /* Private data for SF file */
  21. typedef struct sfstuff {
  22.     struct sfinfo info;
  23. } *sf_t;
  24.  
  25. IMPORT int summary, verbose;
  26.  
  27. /*
  28.  * Read the codes from the sound file, allocate space for the comment and
  29.  * assign its pointer to the comment field in ft.
  30.  */
  31. readcodes(ft, sfhead)
  32. ft_t ft;
  33. SFHEADER *sfhead;
  34. {
  35.     char *commentbuf = NULL, *sfcharp, *newline;
  36.     short bsize, finished = 0;
  37.     SFCODE *sfcodep;
  38.  
  39.     sfcodep = (SFCODE *) &sfcodes(sfhead);
  40.     do {
  41.         sfcharp = (char *) sfcodep + sizeof(SFCODE);
  42.         if (ft->swap) {
  43.             sfcodep->bsize = swapl(sfcodep->bsize);
  44.             sfcodep->code = swapl(sfcodep->code);
  45.         }
  46.         bsize = sfcodep->bsize - sizeof(SFCODE);
  47.         switch(sfcodep->code) {
  48.         case SF_END:
  49.             finished = 1;
  50.             break;
  51.         case SF_COMMENT:
  52.             if((commentbuf = (char *) malloc(bsize + 1)) != NULL) {
  53.                 bcopy(sfcharp, commentbuf, bsize);
  54.                 report("IRCAM comment: %s", sfcharp);
  55.                 commentbuf[bsize] = '\0';
  56.                 if((newline = strchr(commentbuf, '\n')) != NULL)
  57.                     *newline = '\0';
  58.             }
  59.             break;
  60.         }
  61.         sfcodep = (SFCODE *) (sfcharp + bsize);
  62.     } while(!finished);
  63.     if(commentbuf != NULL)    /* handles out of memory condition as well */
  64.         ft->comment = commentbuf;
  65. }
  66.  
  67. /*
  68.  * Do anything required before you start reading samples.
  69.  * Read file header. 
  70.  *    Find out sampling rate, 
  71.  *    size and style of samples, 
  72.  *    mono/stereo/quad.
  73.  */
  74. sfstartread(ft) 
  75. ft_t ft;
  76. {
  77.     sf_t sf = (sf_t) ft->priv;
  78.     SFHEADER sfhead;
  79.     int i;
  80.     
  81.     if (fread(&sfhead, 1, sizeof(SFHEADER), ft->fp) != sizeof(SFHEADER))
  82.         fail("unexpected EOF in SF header");
  83.     bcopy(&sfhead.sfinfo, &sf->info, sizeof(struct sfinfo));
  84.     if (ft->swap) {
  85.         sf->info.sf_magic = swapl(sf->info.sf_magic);
  86.         sf->info.sf_srate = swapl(sf->info.sf_srate);
  87.         sf->info.sf_packmode = swapl(sf->info.sf_packmode);
  88.         sf->info.sf_chans = swapl(sf->info.sf_chans);
  89.     }
  90.     if (sf->info.sf_magic != SF_MAGIC)
  91.         if (sf->info.sf_magic == swapl(SF_MAGIC))
  92.             fail("SF %s file: can't read, it is probably byte-swapped");
  93.         else
  94.             fail("SF %s file: can't read, it is not an IRCAM SoundFile");
  95.  
  96.     /*
  97.      * If your format specifies or your file header contains
  98.      * any of the following information. 
  99.      */
  100.     ft->info.rate = sf->info.sf_srate;
  101.     switch(sf->info.sf_packmode) {
  102.         case SF_SHORT:
  103.             ft->info.size = WORD;
  104.             ft->info.style = SIGN2;
  105.             break;
  106.         case SF_FLOAT:
  107.             ft->info.size = FLOAT;
  108.             ft->info.style = SIGN2;
  109.             break;
  110.         default:
  111.             fail("Soundfile input: unknown format 0x%x\n",
  112.                 sf->info.sf_packmode);
  113.     }
  114.     ft->info.channels = sf->info.sf_chans;
  115.  
  116.     /* Read codes and print as comments. */
  117.     readcodes(ft, &sfhead);
  118. }
  119.  
  120. sfstartwrite(ft) 
  121. ft_t ft;
  122. {
  123.     sf_t sf = (sf_t) ft->priv;
  124.     SFHEADER sfhead;
  125.     SFCODE *sfcodep;
  126.     char *sfcharp;
  127.     int i;
  128.  
  129.     sf->info.sf_magic = SF_MAGIC;
  130.     sf->info.sf_srate = ft->info.rate;
  131. #ifdef    LATER
  132.     /* 
  133.      * CSound sound-files have many formats. 
  134.      * We stick with the IRCAM short-or-float scheme.
  135.      */
  136.     if (ft->info.size == WORD) {
  137.         sf->info.sf_packmode = SF_SHORT;
  138.         ft->info.style = SIGN2;        /* Default to signed words */
  139.     } else if (ft->info.size == FLOAT)
  140.         sf->info.sf_packmode = SF_FLOAT;
  141.     else
  142.         fail("SoundFile %s: must set output as signed shorts or floats",
  143.             ft->filename);
  144. #else
  145.     if (ft->info.size == FLOAT) {
  146.         sf->info.sf_packmode = SF_FLOAT;
  147.         ft->info.size = FLOAT;
  148.     } else {
  149.         sf->info.sf_packmode = SF_SHORT;
  150.         ft->info.size = WORD;
  151.         ft->info.style = SIGN2;        /* Default to signed words */
  152.     }
  153. #endif
  154.     sf->info.sf_chans = ft->info.channels;
  155.  
  156.     bcopy(&sf->info, &sfhead.sfinfo, sizeof(struct sfinfo));
  157.     sfcodep = (SFCODE *) &sfcodes(&sfhead);
  158.     sfcodep->code = SF_COMMENT;
  159.     sfcodep->bsize = strlen(ft->comment) + sizeof(SFCODE);
  160.     sfcharp = (char *) sfcodep;
  161.     strcpy(sfcharp + sizeof(SFCODE), ft->comment);
  162.     sfcodep = (SFCODE *) (sfcharp + sfcodep->bsize);
  163.     sfcodep->code = SF_END;
  164.     sfcodep->bsize = sizeof(SFCODE);
  165.     sfcharp = (char *) sfcodep + sizeof(SFCODE);
  166.     while(sfcharp < (char *) &sfhead + SIZEOF_BSD_HEADER)
  167.         *sfcharp++ = '\0';
  168.     (void) fwrite(&sfhead, 1, sizeof(SFHEADER), ft->fp);
  169. }
  170.  
  171. /* Read and write are supplied by raw.c */
  172.  
  173.  
  174.  
  175.